#include <string>
#include <vector>
#include<iostream>
#include <cstdlib> // 用于rand()
#include <ctime>   // 用于time()
#include <limits>
#include"Monster.h"
#include"Skill.h"
#include "Character.h"
#include"Equipment.h"
#include"GameManager.h"
using namespace std;




Character::Character(std::string name, std::string info, int h, int at, int de, int m)
	: characterName(name), characterInfo(info),
	currentHealth(h), maxHealth(h),
	baseAttack(at), baseDefense(de),
	mp(m), maxMP(m), defeatedMonstersCount(0) {
	// 初始化随机种子
	std::srand(static_cast<unsigned int>(std::time(nullptr)));
}

#pragma region"玩家战斗回合"
void Character::Attack(Monster& monster) {
	if (!monster.isAlive()) {
		std::cout << monster.getName() << "已经死亡，无法攻击！\n";
		return;
	}

    if (stun)
    {
        std::cout << "玩家被晕眩，无法进行攻击" << std::endl;
        stun = false;
        return;
    }

    uniqueEffect();
	int totalAttack = getTotalAttack();

	std::cout << characterName << "对" << monster.getName()
		<< "发动攻击！(攻击力: " << totalAttack << ")\n";

	monster.OnTakeDamage(totalAttack);
}

void Character::UseSkill(int index, Monster& monster) {
	if (index < 0 || index >= skills.size()) {
		std::cout << "无效的技能选择！\n";
		return;
	}

	Skill& skill = skills[index];
	if (mp < skill.cost) {
		std::cout << "MP不足，无法使用" << skill.name << "！\n";
		return;
	}

	mp -= skill.cost;
	std::cout << characterName << "使用了 " << skill.name << "！\n";
	std::cout << "消耗了" << skill.cost << "点MP\n";

	//TODO::Skill添加倍率属性
    int skillIncrease = int(0.5 * baseAttack);
	monster.OnTakeDamage(skills[index].attack+skillIncrease);
}

void Character::EndTurn()
{

}


void Character::OnTakeDamage(int value) {
    int final = value - getDefense();
    if (final < 1) final = 1;

    currentHealth -= final;
    if (currentHealth < 0) currentHealth = 0;

    std::cout << characterName << "受到了 " << final << " 点伤害！\n";
    std::cout << "当前生命值: " << currentHealth << "/" << maxHealth << "\n";

    if (currentHealth <= 0) {
        OnDie();
    }
}

void Character::OnDie() {
    std::cout << ">> " << characterName << "已被击败！ <<\n";
    //TODO 死亡逻辑
}
#pragma endregion

#pragma region "装备管理"
bool Character::addEquipment(const Equipment& equipment) {
    if (equipments.size() < 3) {
        equipments.push_back(equipment);
        
        std::cout << "装备了" << equipment.name << "！\n";
        applyEquipmentBonuses();
        for (const Skill& skill : equipment.getSkills()) {
            // 检查是否已存在相同技能
            bool skillExists = false;
            for (const Skill& existing : skills) {
                if (existing.name == skill.name) {
                    skillExists = true;
                    break;
                }
            }

            
            
            
        }
        return true;
    }
    else {
        std::cout << "装备栏已满！请选择替换或放弃：\n";
        showEquipments();
        std::cout << "0. 放弃\n";

        int choice;
        while (true) {
            std::cin >> choice;
            if (std::cin.fail()) {
                std::cin.clear();
                std::string dummy;
                std::getline(std::cin, dummy);  // 丢弃这一行
                std::cout << "无效输入，请重新选择: ";
                continue;
            }

            if (choice == 0) {
                std::cout << "放弃了" << equipment.name << "\n";
                return false;
            }
            else if (choice >= 1 && choice <= 3) {
                replaceEquipment(choice - 1, equipment);
                return true;
            }
            else {
                std::cout << "无效选择，请重新输入: ";
            }
        }
    }
}

void Character::unequipEquipment(int index) {
    if (index < 0 || index >= equipments.size()) return;

    // 记录要移除的装备技能
    std::vector<std::string> skillsToRemove;
    for (const Skill& skill : equipments[index].getSkills()) {
        skillsToRemove.push_back(skill.name);
    }

    // 移除装备
    equipments.erase(equipments.begin() + index);

    // 移除关联技能
    for (auto it = skills.begin(); it != skills.end(); ) {
        if (std::find(skillsToRemove.begin(), skillsToRemove.end(), it->name) != skillsToRemove.end()) {
            std::cout << "遗忘了装备技能: " << it->name << "\n";
            it = skills.erase(it);
        }
        else {
            ++it;
        }
    }

    applyEquipmentBonuses();
}
void Character::replaceEquipment(int index, const Equipment& newEquipment) {
    if (index < 0 || index >= equipments.size()) return;

    std::cout << "将" << equipments[index].name << "替换为" << newEquipment.name << "\n";
    equipments[index] = newEquipment;
    applyEquipmentBonuses();
}

void Character::applyEquipmentBonuses() {
    // 重置基础属性
    int totalHealthBonus = 0;
    int totalAttackBonus = 0;
    int totalDefenseBonus = 0;

    // 计算所有装备加成
    for (const Equipment& eq : equipments) {
        totalAttackBonus += eq.attackBonus;
        totalDefenseBonus += eq.defenseBonus;
        totalHealthBonus += eq.healthBonus;
    }

    // 更新属性
    maxHealth += totalHealthBonus;
    currentHealth += totalHealthBonus;


    // 更新技能列表
    updateSkillList();
}
#pragma endregion

#pragma region "技能管理"
bool Character::addSkill(const Skill& skill) {
    if (skills.size() < 3) {
        skills.push_back(skill);
        std::cout << "学会了" << skill.name << "！\n";
        return true;
    }
    else {
        std::cout << "技能栏已满！请选择替换或放弃：\n";
        showSkills();
        std::cout << "0. 放弃\n";

        int choice;
        while (true) {
            std::cin >> choice;
            if (std::cin.fail()) {
                std::cin.clear();
                std::string dummy;
                std::getline(std::cin, dummy);  // 丢弃这一行
                std::cout << "无效输入，请重新选择: ";
                continue;
            }

            if (choice == 0) {
                std::cout << "放弃了" << skill.name << "\n";
                return false;
            }
            else if (choice >= 1 && choice <= 3) {
                replaceSkill(choice - 1, skill);
                return true;
            }
            else {
                std::cout << "无效选择，请重新输入: ";
            }
        }
    }
}

void Character::updateSkillList() {
    // 清空当前技能列表（保留基础技能）


    // 添加所有装备技能
    for (const Equipment& eq : equipments) {
        for (const Skill& skill : eq.getSkills()) {
            // 避免重复添加相同技能
            bool exists = false;
            for (const Skill& existing : skills) {
                if (existing.name == skill.name) {
                    exists = true;
                    break;
                }
            }

            if (!exists) {

                if (skills.size() < 3)
                {
                    skills.push_back(skill);
                    std::cout << "学会了" << skill.name << endl;
                }
                else
                {
                    std::cout << "技能栏已满！请选择替换或放弃：\n";
                    showSkills();
                    std::cout << "0. 放弃\n";

                    int choice;
                    while (true) {
                        std::cin >> choice;
                        if (std::cin.fail()) {
                            std::cin.clear();
                            std::string dummy;
                            std::getline(std::cin, dummy);  // 丢弃这一行
                            std::cout << "无效输入，请重新选择: ";
                            continue;
                        }

                        if (choice == 0) {
                            std::cout << "放弃了" << skill.name << "\n";
                            return;
                        }
                        else if (choice >= 1 && choice <= 3) {
                            replaceSkill(choice - 1, skill);
                            return;
                        }
                        else {
                            std::cout << "无效选择，请重新输入: ";
                        }
                    }
                }
                //TODO

            }
        }
    }
}

void Character::replaceSkill(int index, const Skill& newSkill) {
    if (index < 0 || index >= skills.size()) return;

    std::cout << "将" << skills[index].name << "替换为" << newSkill.name << "\n";
    skills[index] = newSkill;
}
#pragma endregion


#pragma region"怪物击败后逻辑"
void Character::defeatMonster() {
    defeatedMonstersCount++;
    EndTurn();
    std::cout << "已击败怪物数: " << defeatedMonstersCount << "\n";
    GameManager& game = GameManager::getInstance();
    // 每击败3个怪物获得装备
    if (defeatedMonstersCount % 3 == 0) 
    {
        
        Equipment newEquipment = GameManager::getInstance().getRandomEquipment(game.currentDifficulty);
        std::cout << "\n击败3个怪物，获得了新装备: " << newEquipment.name << "！\n";
        std::cout << newEquipment.Info << "\n";
        addEquipment(newEquipment);
    }

    // 每击败5个怪物获得技能
    if (defeatedMonstersCount % 5 == 0) 
    {
        
        Skill newSkill = GameManager::getInstance().getRandomSkill(game.currentDifficulty);
        std::cout << "\n击败5个怪物，获得了新技能: " << newSkill.name << "！\n";
        std::cout << newSkill.Info << " (消耗MP: " << newSkill.cost << ")\n";
        addSkill(newSkill);
    }
}
#pragma endregion

#pragma region"信息显示"
void Character::showSkills() const {
    if (skills.empty()) {
        std::cout << "没有可用技能\n";
        return;
    }

    for (int i = 0; i < skills.size(); i++) {
        std::cout << i + 1 << ". " << skills[i].name
            << " (消耗MP: " << skills[i].cost << ")"
            << " - " << skills[i].Info << "\n";
    }
}

void Character::showEquipments() const {
    if (equipments.empty()) {
        std::cout << "没有装备\n";
        return;
    }

    for (int i = 0; i < equipments.size(); i++) {
        std::cout << i + 1 << ". " << equipments[i].name
            << " (攻击+" << equipments[i].attackBonus
            << ", 防御+" << equipments[i].defenseBonus
            << ", 生命+" << equipments[i].healthBonus << ")"
            << " - " << equipments[i].Info << "\n";
    }
}
#pragma endregion

#pragma region"属性获取"
std::string Character::getName() const { return characterName; }
std::string Character::getInfo() const { return characterInfo; }
int Character::getCurrentHealth() const { return currentHealth; }
int Character::getMaxHealth() const { return maxHealth; }
int Character::getDefense() const {
    int totalDefense = baseDefense;
    for (const Equipment& eq : equipments) {
        totalDefense += eq.defenseBonus;
    }
    return totalDefense;
}
int Character::getMP() const { return mp; }
int Character::getMaxMP() const { return maxMP; }
int Character::getTotalAttack() const {
    int totalAttack = baseAttack;
    for (const Equipment& eq : equipments) {
        totalAttack += eq.attackBonus;
    }
    return totalAttack;
}

int Character::getDefeatedCount() const
{
    return defeatedMonstersCount;
}

void Character::setBaseAttack(int value)
{
    baseAttack += value;
}

void Character::setBaseDefense(int value)
{
    baseDefense += value;
}

void Character::setCurrentHealth(int value)
{
    int temp = currentHealth + value;
    if (temp >= maxHealth)
    {
        currentHealth = maxHealth;
    }
    else
    {
        currentHealth += value;
    }
}

void Character::setCurrentMP(int value)
{
    mp = value;
}

void Character::isLoad(bool value)
{
    m_fromSave = value;
}

void Character::RecoilState()
{
    int tempHP = (int)maxHealth*0.3;
    int tempMP = (int)maxMP*0.3;
    if (currentHealth + tempHP >= maxHealth)
    {
        currentHealth = maxHealth;
    }
    else
    {
        currentHealth += tempHP;
    }

    if (mp + tempMP >= maxMP)
    {
        mp = maxMP;
    }
    else
    {
        mp += tempMP;
    }
}
#pragma endregion

#pragma region JSON
json Character::toJson() const {
    json j;
    j["type"] = getType();
    j["name"] = characterName;
    j["info"] = characterInfo;
    j["maxHealth"] = maxHealth;
    j["currentHealth"] = currentHealth;
    j["attack"] = baseAttack;
    j["defense"] = baseDefense;
    j["maxMP"] = maxMP;
    j["currentMP"] = mp;
    j["defeatedCount"] = defeatedMonstersCount;
    // 装备
    j["equipments"] = json::array();
    for (const auto& e : equipments) j["equipments"].push_back(e.toJson());
    // 技能
    j["skills"] = json::array();
    for (const auto& s : skills) j["skills"].push_back(s.toJson());
    return j;
}

Character* Character::fromJson(const json& j) {
    try {
        std::string type = j.value("type", "");
        std::string name = j.value("name", "未知");
        std::string info = j.value("info", "暂无描述");
        int maxHP = j.value("maxHealth", 100);
        int atk = j.value("attack", 10);
        int def = j.value("defense", 5);
        int mp = j.value("maxMP", 50);

        Character* obj = nullptr;

        if (type == "Warrior") obj = new Warrior(name, info, maxHP, atk, def, mp);
        else if (type == "Mage") obj = new Mage(name, info, maxHP, atk, def, mp);
        else if (type == "Archer") obj = new Archer(name, info, maxHP, atk, def, mp);
        else return nullptr;

        // 设置当前生命和MP（可选字段）
        obj->currentHealth = j.value("currentHealth", maxHP);
        obj->mp = j.value("currentMP", mp);
        obj->defeatedMonstersCount = j.value("defeatedCount", 0);

        
        
        

        if (j.contains("equipments")) {
            obj->equipments.clear();
            for (auto& ej : j["equipments"]) {
                obj->equipments.push_back(Equipment::fromJson(ej));
            }

            // 只更新属性加成，不更新技能
            int totalHealthBonus = 0;
            int totalAttackBonus = 0;
            int totalDefenseBonus = 0;

            for (const Equipment& eq : obj->equipments) {
                totalAttackBonus += eq.attackBonus;
                totalDefenseBonus += eq.defenseBonus;
                totalHealthBonus += eq.healthBonus;
            }

            obj->maxHealth += totalHealthBonus;
            obj->currentHealth += totalHealthBonus;
            obj->baseAttack += totalAttackBonus;
            obj->baseDefense += totalDefenseBonus;
        }

        // 读取技能
        if (j.contains("skills")) {
            obj->skills.clear();
            for (auto& sj : j["skills"])
                obj->skills.push_back(Skill::fromJson(sj));
        }

        return obj;
    }
    catch (const std::exception& e) {
        std::cerr << "[fromJson Exception] " << e.what() << std::endl;
        return nullptr;
    }
}
#pragma endregion